package com.ruoyi.web.controller.crm.stock;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import com.ruoyi.common.annotation.Log;
import com.ruoyi.common.core.controller.BaseController;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.core.domain.entity.SysDept;
import com.ruoyi.common.core.domain.entity.SysUser;
import com.ruoyi.common.core.domain.TreeSelect;
import com.ruoyi.common.enums.BusinessType;
import com.ruoyi.crm.domain.CrmStockMedicine;
import com.ruoyi.crm.service.ICrmStockMedicineService;

import com.ruoyi.common.core.page.TableDataInfo;
import com.ruoyi.system.service.ISysDeptService;
import com.ruoyi.system.service.ISysUserService;

/**
 * 药品信息Controller
 *
 * @author ruoyi
 */
@RestController
@RequestMapping("/crm/stock/medicine")
public class CrmStockMedicineController extends BaseController {

    @Autowired
    private ICrmStockMedicineService crmStockMedicineService;

    

    @Autowired
    private ISysDeptService deptService;

    @Autowired
    private ISysUserService userService;

    /**
     * 查询药品信息列表
     */
    @PreAuthorize("@ss.hasPermi('crm:stock:medicine:list')")
    @GetMapping("/list")
    public TableDataInfo list(CrmStockMedicine crmStockMedicine) {
        startPage();
        List<CrmStockMedicine> list = crmStockMedicineService.selectCrmStockMedicineList(crmStockMedicine);
        return getDataTable(list);
    }

    /**
     * 根据用户ID查询药品信息列表
     */
    @PreAuthorize("@ss.hasPermi('crm:stock:medicine:list')")
    @GetMapping("/listByUser")
    public TableDataInfo listByUser(CrmStockMedicine crmStockMedicine) {
        startPage();
        // 获取当前用户ID
        Long userId = com.ruoyi.common.utils.SecurityUtils.getLoginUser().getUser().getUserId();
        List<CrmStockMedicine> list = crmStockMedicineService.selectCrmStockMedicineList(crmStockMedicine);
        return getDataTable(list);
    }

    /**
     * 获取用户可见药品信息列表（根据权限）
     */
    @PreAuthorize("@ss.hasPermi('crm:stock:medicine:list')")
    @GetMapping("/listByAuth")
    public TableDataInfo listByAuth(CrmStockMedicine crmStockMedicine) {
        startPage();
        // 查询所有药品数据，不根据用户权限过滤
        List<CrmStockMedicine> list = crmStockMedicineService.selectCrmStockMedicineList(crmStockMedicine);
        return getDataTable(list);
    }

    /**
     * 获取药品信息详细信息
     */
    @PreAuthorize("@ss.hasPermi('crm:stock:medicine:query')")
    @GetMapping(value = "/{medicineId}")
    public AjaxResult getInfo(@PathVariable("medicineId") Long medicineId) {
        return success(crmStockMedicineService.selectCrmStockMedicineById(medicineId));
    }

    /**
     * 新增药品信息
     */
    @PreAuthorize("@ss.hasPermi('crm:stock:medicine:add')")
    @Log(title = "药品信息", businessType = BusinessType.INSERT)
    @PostMapping
    public AjaxResult add(@RequestBody CrmStockMedicine crmStockMedicine) {
        crmStockMedicine.setCreateBy(getUsername());
        crmStockMedicine.setCreateTime(new Date());
        return toAjax(crmStockMedicineService.insertCrmStockMedicine(crmStockMedicine));
    }

    /**
     * 修改药品信息
     */
    @PreAuthorize("@ss.hasPermi('crm:stock:medicine:edit')")
    @Log(title = "药品信息", businessType = BusinessType.UPDATE)
    @PutMapping
    public AjaxResult edit(@RequestBody CrmStockMedicine crmStockMedicine) {
        crmStockMedicine.setUpdateBy(getUsername());
        return toAjax(crmStockMedicineService.updateCrmStockMedicine(crmStockMedicine));
    }

    /**
     * 删除药品信息
     */
    @PreAuthorize("@ss.hasPermi('crm:stock:medicine:remove')")
    @Log(title = "药品信息", businessType = BusinessType.DELETE)
    @DeleteMapping("/{medicineIds}")
    public AjaxResult remove(@PathVariable Long[] medicineIds) {
        return toAjax(crmStockMedicineService.deleteCrmStockMedicineByIds(medicineIds));
    }

    

    /**
     * 查询部门和用户树结构
     */
    @PreAuthorize("@ss.hasPermi('crm:stock:medicine:viewUsers')")
    @GetMapping("/deptUserTree")
    public AjaxResult deptUserTree() {
        try {
            // 获取所有部门列表
            List<SysDept> allDepts = deptService.selectDeptList(new SysDept());
            // 获取所有用户列表
            List<SysUser> allUsers = userService.selectUserList(new SysUser());
            // 构建部门-用户树结构
            List<TreeSelect> deptUserTree = buildDeptUserTree(allDepts, allUsers);
            return AjaxResult.success(deptUserTree);
        } catch (Exception e) {
            e.printStackTrace();
            return AjaxResult.error("构建部门用户树失败: " + e.getMessage());
        }
    }

    /**
     * 构建部门-用户树结构
     * @param allDepts 所有部门列表
     * @param allUsers 所有用户列表
     * @return 部门-用户树
     */
    private List<TreeSelect> buildDeptUserTree(List<SysDept> allDepts, List<SysUser> allUsers) {
        // 构建父ID到部门的映射，便于快速查找子部门
        Map<Long, List<SysDept>> parentDeptMap = allDepts.stream()
            .filter(dept -> dept.getParentId() != null) // 过滤掉父ID为null的部门
            .collect(Collectors.groupingBy(SysDept::getParentId));
        
        // 构建部门ID到用户的映射，便于快速查找部门下的用户
        Map<Long, List<SysUser>> deptUserMap = allUsers.stream()
            .filter(user -> user.getDeptId() != null) // 过滤掉部门ID为null的用户
            .collect(Collectors.groupingBy(SysUser::getDeptId));
        
        // 获取根部门（父ID为0或null的部门）
        List<SysDept> rootDepts = allDepts.stream()
            .filter(dept -> dept.getParentId() == null || dept.getParentId() == 0)
            .collect(Collectors.toList());
        
        // 递归构建树结构，只保留有用户的部门和其父级部门
        return rootDepts.stream()
            .map(dept -> buildDeptUserTreeRecursive(dept, parentDeptMap, deptUserMap))
            .filter(this::hasUsersOrChildrenWithUsers) // 只保留有用户或有子部门包含用户的部门
            .collect(Collectors.toList());
    }
    
    /**
     * 递归构建部门-用户树结构
     * @param dept 当前部门
     * @param parentDeptMap 父ID到部门的映射
     * @param deptUserMap 部门ID到用户的映射
     * @return 部门-用户树节点
     */
    private TreeSelect buildDeptUserTreeRecursive(SysDept dept, Map<Long, List<SysDept>> parentDeptMap,
            Map<Long, List<SysUser>> deptUserMap) {
        TreeSelect treeSelect = new TreeSelect(dept);

        // 获取当前部门下的用户
        List<SysUser> usersInDept = deptUserMap.get(dept.getDeptId());
        if (usersInDept != null && !usersInDept.isEmpty()) {
            // 添加用户节点作为部门的子节点
            for (SysUser user : usersInDept) {
                TreeSelect userNode = new TreeSelect();
                userNode.setId(user.getUserId());
                userNode.setLabel(user.getNickName() != null && !user.getNickName().isEmpty() ? 
                                  user.getNickName() : user.getUserName());
                userNode.setChildren(new ArrayList<>());
                treeSelect.getChildren().add(userNode);
            }
        }

        // 获取当前部门的直接子部门
        List<SysDept> childDepts = parentDeptMap.get(dept.getDeptId());
        if (childDepts != null && !childDepts.isEmpty()) {
            // 递归处理子部门
            for (SysDept childDept : childDepts) {
                TreeSelect childNode = buildDeptUserTreeRecursive(childDept, parentDeptMap, deptUserMap);
                // 如果子部门有用户或有子部门包含用户，则添加到树中
                if (hasUsersOrChildrenWithUsers(childNode)) {
                    treeSelect.getChildren().add(childNode);
                }
            }
        }

        return treeSelect;
    }
    
    /**
     * 检查节点是否包含用户或有子部门包含用户
     * @param node 树节点
     * @return 是否包含用户或有子部门包含用户
     */
    private boolean hasUsersOrChildrenWithUsers(TreeSelect node) {
        // 检查当前节点是否有直接的用户子节点
        if (node.getChildren() != null) {
            for (TreeSelect child : node.getChildren()) {
                // 如果子节点是用户（没有子节点的节点）
                if (isUserNode(child)) {
                    return true;
                }
            }
        }
        
        // 检查当前节点的子部门是否有用户
        if (node.getChildren() != null && !node.getChildren().isEmpty()) {
            for (TreeSelect child : node.getChildren()) {
                if (hasUsersOrChildrenWithUsers(child)) {
                    return true;
                }
            }
        }
        return false;
    }
    
    /**
     * 判断节点是否为用户节点
     * @param node 树节点
     * @return 是否为用户节点
     */
    private boolean isUserNode(TreeSelect node) {
        // 如果节点没有子节点，通常表示这是一个用户节点
        return (node.getChildren() == null || node.getChildren().isEmpty()) && 
               (node.getId() != null && node.getId() > 0);
    }

}